home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / asmutil / a86v400.zip / A06A.DOC < prev    next >
Text File  |  1994-12-21  |  21KB  |  426 lines

  1. CHAPTER 6    THE 86 INSTRUCTION SET
  2.  
  3.  
  4. In this chapter we discuss in detail the instruction set
  5. supported by both the A86 and A386 assemblers.  To use any of the
  6. 32-bit registers, the extra segment regsiters FS and GS, or the
  7. instructions marked with a "3", "4", or "5" in the instruction
  8. list, you need my A386 assembler, available only if you register
  9. both A86 and D86.
  10.  
  11.  
  12. Effective Addresses
  13.  
  14. Most memory data accessing in the 86 family is accomplished via
  15. the mechanism of the effective address.  Wherever an effective
  16. address specifier "eb", "ew" "ed", or "ev" appears in the list of
  17. instructions, you may use a wide variety of actual operands in
  18. that instruction.  These include general registers, memory
  19. variables, and a variety of indexed memory quantities.
  20.  
  21. GENERAL REGISTERS: Wherever an "ew" appears, you can use any of
  22. the 16-bit registers AX,BX,CX,DX,SI,DI,SP, or BP.  Wherever an
  23. "eb" appears, you can use any of the 8-bit registers
  24. AL,BL,CL,DL,AH,BH,CH, or DH.  Whenever an "ed" occurs, you can
  25. (on A386) use any of the 32-bit registers
  26. EAX,EBX,ECX,EDX,ESI,EDI,EBP, or ESP.  For A86, "ev" is the same
  27. as "ew"; for A386, it means you can use either a 16-bit or a
  28. 32-bit register.  For example, the "ADD ev,rv" form subsumes the
  29. 16-bit register-to-register adds; for example, ADD AX,BX; ADD
  30. SI,BP; ADD SP,AX.  On A386, this form also includes 32-bit
  31. register-to-register adds; e.g., ADD EBX,ESI.  At the machine
  32. level the 16-vs.-32 distinction is made by an "operand override"
  33. opcode byte, 66H, that A386 places before the instruction to
  34. signal a switch from 16-bits to 32-bits.
  35.  
  36. MEMORY VARIABLES: Wherever an "eb", "ew", "ed", or "ev" appears,
  37. you can use a memory variable of the indicated size: byte, word,
  38. doubleword, or either-word-or-doubleword.  Variables are
  39. typically declared in the DATA segment, using a DD declaration
  40. for a doubleword variable, a DW declaration for a word variable,
  41. or a DB declaration for a byte variable.  For example, you can
  42. declare variables:
  43.  
  44.      DATA_PTR  DW ?
  45.      ESC_CHAR  DB ?
  46.  
  47. Later, you can load or store these variables:
  48.  
  49.      MOV ESC_CHAR,BL    ; store the byte variable ESC_CHAR
  50.      MOV DATA_PTR,081   ; initialize DATA_PTR
  51.      MOV SI,DATA_PTR    ; load DATA_PTR into SI for use
  52.      LODSW              ; fetch the word pointed to by DATA_PTR
  53.  
  54. Alternatively, you can address specific unnamed memory locations
  55. by enclosing the location value in square brackets; for example,
  56.  
  57.      MOV AL,[02000]     ; load contents of location 02000 into AL
  58.                                                               6-2
  59.  
  60. Note that A86 discerned from context (loading into AL) that a
  61. BYTE at 02000 was intended.  Sometimes this is impossible, and
  62. you must specify byte or word:
  63.  
  64.      INC B[02000]       ; increment the byte at location 02000
  65.      MOV W[02000],0     ; set the WORD at location 02000 to zero
  66.  
  67.  
  68. INDEXED MEMORY: The 86 supports the use of certain registers as
  69. base pointers and index registers into memory.  BX and BP are the
  70. base registers; SI and DI are the index registers.  You may
  71. combine at most one base register, at most one index register,
  72. and a constant number into a run time pointer that determines the
  73. location of the effective address memory to be used in the
  74. instruction.  These can be given explicitly, by enclosing the
  75. index registers in brackets:
  76.  
  77.      MOV AX,[BX]
  78.      MOV CX,W[SI+17]
  79.      MOV AX,[BX+SI+5]
  80.      MOV AX,[BX][SI]5   ; another way to write the same instr.
  81.  
  82. Or, indexing can be accomplished by declaring variables in a
  83. based structure (see the STRUC directive in Chapter 9):
  84.  
  85.      STRUC [BP]        ; NOTE: based structures are unique to A86!
  86.        BP_SAVE   DW ?  ; BP_SAVE is a word at [BP]
  87.        RET_ADDR  DW ?  ; RET_ADDR is a word at [BP+2]
  88.        PARM1     DW ?  ; PARM1 is a word at [BP+4]
  89.        PARM2     DW ?  ; PARM2 is a word at [BP+6]
  90.      ENDS              ; end of structure
  91.      INC PARM1         ; equivalent to INC W[BP+4]
  92.  
  93. Finally, indexing can be done by mixing explicit components with
  94. declared ones:
  95.  
  96.      TABLE DB 4,2,1,3,5
  97.      MOV AL,TABLE[BX]      ; load byte number BX of TABLE
  98.  
  99. The 386 processor also supports indexing using any of the eight
  100. 32-bit general registers.  This type of indexing is of limited
  101. use for memory referencing from real-mode programs (most programs
  102. running under DOS), since offsets greater than 64K are disallowed
  103. in real mode (you will get a General Protection Fault if you try
  104. it).  32-bit indexing is, however, useful in conjunction with the
  105. LEA instruction, giving an extremely powerful register arithmetic
  106. instruction.  For example, LEA ECX,[EAX+2*EBX+17000] performs two
  107. additions and a multiplication, all in a single machine
  108. instruction.  Since no memory accessed is actually attempted,
  109. this kind of LEA usage is allowed in real-mode DOS programs.
  110.  
  111. At the time of this writing, my A386 assembler does not yet
  112. support 32-bit indexing; I hope to add it soon.  If you have A386
  113. on your registered A86+D86 disk, see the A386.DOC file for the
  114. latest implementation news.
  115.                                                               6-3
  116.  
  117. In 32-bit indexing, you may use one or two of any of the 32-bit
  118. general registers.  You may also scale one of the indexing
  119. registers, by multiplying it by 2, 4, or 8.  You may also add or
  120. subtract a constant of any size up to a doubleword capacity to
  121. the indexed quantity.  If you use the same register twice and
  122. scale one of the instances of that register, you get, in effect,
  123. an odd-number scaling (3, 5, or 9) of that register; e.g., A386
  124. will allow LEA EAX,[9*EBX] as an abbreviation for LEA
  125. EAX,[8*EBX+EBX].
  126.  
  127. Due to coding restrictions, the ESP register can be used only
  128. once within an indexed quantity, and cannot be scaled.
  129.  
  130. Some more examples of 32-bit indexing are:
  131.  
  132.      XCHG DX,[EAX]
  133.      MOV AL,[EAX+EBX]
  134.      ADD EBX,[ESI+8*ECX+3391811]
  135.      LEA ECX,[4*EBX-7]
  136.  
  137.  
  138.  
  139. Segmentation and Effective Addresses
  140.  
  141. The 86 family has four segment registers, CS, DS, ES, and SS,
  142. used to address memory.  The 386 and later processors add two
  143. more segment registers FS and GS.  Each segment register points
  144. to 64K bytes of memory within the 1-megabyte memory space of the
  145. 86. (The start of the 64K is calculated by multiplying the
  146. segment register value by 16; i.e., by shifting the value left by
  147. one hex digit.)  If your program's code, data and stack areas can
  148. all fit in the same 64K bytes, you can leave all the segment
  149. registers set to the same value.  In that case, you won't have to
  150. think about segment registers: no matter which one is used to
  151. address memory, you'll still get the same 64K.  If your program
  152. needs more than 64K, you must point one or more segment registers
  153. to other parts of the memory space.  In this case, you must take
  154. care that your memory references use the segment registers you
  155. intended.
  156.  
  157. Each effective address memory access has a default segment
  158. register, to be used if you do not explicitly specify which
  159. segment register you wish.  For most effective addresses, the
  160. default segment register is DS.  The exceptions are those
  161. effective addresses that use the BP register for indexing.  All
  162. BP-indexed memory references have a default of SS.  (This is
  163. because BP is intended to be used for addressing local variables,
  164. stored on the stack.)
  165.                                                               6-4
  166.  
  167. If you wish your memory access to use a different segment
  168. register, you provide a segment override byte before the
  169. instruction containing the effective address operand.  In the A86
  170. language, you code the override by giving the name of the segment
  171. register you wish before the instruction mnemonic.  For example,
  172. suppose you want to load the AL register with the memory byte
  173. pointed to by BX.  If you code MOV AL,[BX], the DS register will
  174. be used to determine which 64K segment BX is pointing to.  If you
  175. want the byte to come from the CS-segment instead, you code CS
  176. MOV AL,[BX].  Be aware that the segment override byte has effect
  177. only upon the single instruction that follows it.  If you hav